package com.agile.leetcode.reflex.finalreflex;

import org.junit.Test;

import java.lang.reflect.Field;

/**
 * final修饰的变量反射获取内联优化的演示
 *
 * @Author KD
 * @Date 2021/1/28 15:51
 */
public class FinalReflexDemo {
    // 定义常量
    private final String name = "czk";
    private Person person = new Person(15, "kd");
    private static Integer age = 15;

    public Person getPerson() {
        return person;
    }

    public String getName() {
        return name;
    }

    /**
     * 创建对象的效率对比
     *
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Test
    public void test2() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        // 首先得到字节码对象
        Class<?> clazz = Class.forName("com.agile.leetcode.reflex.finalreflex.FinalReflexDemo");
        FinalReflexDemo demo;
        int i = 0;
        // 当前时间
        long currentTimeMillis = System.currentTimeMillis();
        while (i < 1000000) {
            i++;
            // 直接实例化 16
            // demo = new FinalReflexDemo();
            // clazz反射 28
            // demo = (FinalReflexDemo) clazz.newInstance();
            // 每次class.forName()反射 1036 效率大大降低
            demo = (FinalReflexDemo) Class.forName("com.agile.leetcode.reflex.finalreflex.FinalReflexDemo").newInstance();
        }
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - currentTimeMillis);
    }

    /**
     * 反射获取静态变量的值
     *
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    @Test
    public void test1() throws NoSuchFieldException, IllegalAccessException {
        FinalReflexDemo demo = new FinalReflexDemo();
        // 获取字节码对象
        Class<? extends FinalReflexDemo> clazz = demo.getClass();
        // 获取静态变量的值
        Field field = clazz.getDeclaredField("age");
        // 设置访问属性
        field.setAccessible(true);
        // 获取静态变量的值，由于其不随对象变化，在类加载初始化时进行赋值，所以传入null
        Object o = field.get(null);
        if (o instanceof Integer) {
            int i = (Integer) o;
            System.out.println(i);
        }
    }

    /**
     * 通过反射获取final修饰的变量
     *
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    @Test
    public void test() throws NoSuchFieldException, IllegalAccessException {
        // 拿到字节码对象
        FinalReflexDemo demo = new FinalReflexDemo();
        Class<? extends FinalReflexDemo> clazz = demo.getClass();
        // 拿到域
        Field field = clazz.getDeclaredField("name");
        // 设置访问修饰符
        field.setAccessible(true);
        // 修改变量
        field.set(demo, "nzq");
        // 此时还是czk,因为内联优化已经将 return name->优化成 return "czk";
        System.out.println(demo.getName());
        // 此时是nzq,因为是动态获取
        System.out.println(field.get(demo));
        // 修改person
        Field person = clazz.getDeclaredField("person");
        // 修改值
        person.set(demo, new Person(15, "james"));
        // 打印 james修改成功
        System.out.println(demo.getPerson().getName());

    }


}

class Person {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
}
